import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;


public class Switch implements Comando {

	private Expressao expr;
	private List<Case> cases;
	private LinkedList<AcaoSemantica> defaultCont = new LinkedList<AcaoSemantica>();

	public Switch(Expressao expr, List<Case> cases,
			LinkedList<AcaoSemantica> defaultCont) {
		this.expr = expr;
		this.cases = cases;
		if (defaultCont != null) this.defaultCont = defaultCont;
	}

	@Override
	public String getCode() {
		StringBuffer sb = new StringBuffer();

		String labelFinal = ParserUtils.novoLabel();
		
		List<String> labels = new ArrayList<String>();
		for (int i = 0; i < cases.size()-1; i++) {
			labels.add(ParserUtils.novoLabel());
		}
		if (!defaultCont.isEmpty()) {
			labels.add(ParserUtils.novoLabel());
		}
		
		Integer regTest = null;
		String s1 = expr.getCode();
		if (expr.possuiRegistradorFinal()) {
			regTest = expr.registradorFinal();
			sb.append(s1);
		} else {
			regTest = ParserUtils.novoRegistrador();
			sb.append("LD R" + regTest + ", " + s1);
		}
		sb.append(System.lineSeparator());
		
		for (int i = 0; i < cases.size(); i++) {
			if (i != 0) {
				sb.append(labels.get(i-1) + ": ");
			}
			Case c = cases.get(i);
			Expressao expr2 = c.getExpr();
			Integer regTest2 = null;
			String s2 = expr2.getCode();
			if (expr2.possuiRegistradorFinal()) {
				regTest2 = expr2.registradorFinal();
				sb.append(s2);
			} else {
				regTest2 = ParserUtils.novoRegistrador();
				sb.append("LD R" + regTest2 + ", " + s2);
			}
			sb.append(System.lineSeparator());
			sb.append("SUB R" + regTest2 + ", R" + regTest + ", R"+regTest2);
			if (i != cases.size()-1) {
				sb.append(System.lineSeparator());
				sb.append("JNZ " + labels.get(i) + ", R"+regTest2);
			} 
			if (i == cases.size()-1 && !defaultCont.isEmpty()) {
				sb.append(System.lineSeparator());
				sb.append("JNZ " + labels.get(i) + ", R"+regTest2);
			}
			sb.append(System.lineSeparator());
			sb.append(c.getCode());
			if (c.possuiBreak()) {
				sb.append(System.lineSeparator());
				sb.append("JMP " + labelFinal);
				sb.append(System.lineSeparator());
			}
		}
		sb.append(System.lineSeparator());
		if (!defaultCont.isEmpty()) {
			sb.append(labels.get(labels.size()-1) + ": ");
			for (AcaoSemantica as2 : defaultCont) {
				sb.append(System.lineSeparator());
				sb.append(as2.getCode());
			}
		}
		
		sb.append(System.lineSeparator());
		sb.append(labelFinal + ": ");
		return sb.toString();
	}

}
